<script lang="ts" setup>
import { reactive, ref, onMounted, onActivated, shallowRef, computed } from 'vue'
import SearchPlace from '@/components/map/SearchPlace.vue'
import LocusControlGroup from '@/components/map/LocusControlGroup.vue'
import LocusPoint from '@/components/map/LocusPoint.vue'
import { useMap } from '@/hooks/useMap'
import { ElMessage } from 'element-plus'
import { useRoute } from 'vue-router'
import { getToken } from '@/utils/cache/cookies'
import { queryBikeShortTermTrack } from '@/api/bike'
import { coordinatesType, queryBikeShortTermTrackResponseData } from '@/api/bike/types/bike'
import { useActivated } from '@/hooks/useActivated'
import MarkerIcon from '@/assets/map/bikeLocus/marker.png'
import StartIcon from '@/assets/map/bikeLocus/start.png'
import EndIcon from '@/assets/map/bikeLocus/end.png'
import { returnLocationType } from '@/types/interface'
import returnPointImg from '@/assets/map/bikeLocation/returnPoint.png'
import activeReturnPointImg from '@/assets/map/bikeLocation/activeReturnPoint.png'
import dayjs from 'dayjs'
import duration from 'dayjs/plugin/duration'
import CircleImg from '@/assets/map/bikeLocus/circle.png'
import ActiveCircleImg from '@/assets/map/bikeLocus/activecircle.png'
import MeasureTools from '@/components/map/MeasureTools.vue'
defineOptions({
  name: 'TimeBikeOrderLocus'
})
dayjs.extend(duration)

const route = useRoute()
/** 请求方法 */
const watchParams = reactive({
  orderId: route.query.orderId as string,
  bikeId: route.query.bikeId as string
})
const originData = ref<queryBikeShortTermTrackResponseData>()
const getData = async () => {
  try {
    reset()
    const res = await queryBikeShortTermTrack({
      ...watchParams,
      token: getToken() ?? ''
    })
    if (res.statusCode === '0') {
      if (res.data.bikeGpsList !== null) {
        originData.value = res.data
        coordinates.value = handleCoordinates(res.data.coordinates)
        returnLocation.value = handleReturnLocation(res.data.returnLocations)
        handleOriginData()
        if (NoSingleLngLat.value) {
          await handleStartAndEnd()
          handleCoverInit()
        } else {
          handleSingleCoverInit()
        }
      } else {
        ElMessage.error('暂无数据')
      }
    }
  } catch (error) {
    console.error(error)
  }
}
/** 地图初始化 */
const loading = ref<boolean>(false)
const isInit = ref<boolean>(false)
const mapContainer = ref<HTMLDivElement>()
const center = reactive({
  longtitude: 0,
  latitude: 0
})
const { map, auto, initAmap, placeSearch, geocoder, ruler } = useMap(mapContainer, [
  Number(center.longtitude),
  Number(center.latitude)
])
const init = async () => {
  isInit.value = await initAmap()
  handleInit()
}
const handleInit = () => {
  if (isInit.value && map.value) {
    getData()
  }
}
/** 处理开始骑行点与结束骑行点 */
interface startType {
  LngLat: AMap.LngLat | null
  unlockTime: string
  address: string
}
interface endType {
  LngLat: AMap.LngLat | null
  lockTime: string
  address: string
}
const start = reactive<startType>({ LngLat: null, unlockTime: '', address: '' })
const end = reactive<endType>({ LngLat: null, lockTime: '', address: '' })
const diffDate = ref<string>('')
const handleStartAndEnd = async () => {
  const data = originData.value?.bikeGpsList
  const firstGps = data![0]
  const lastGps = data![data!.length - 1]
  start.unlockTime = firstGps.recordTime
  end.lockTime = lastGps.recordTime
  start.LngLat = new AMap.LngLat(+firstGps.longtitude, +firstGps.latitude)
  end.LngLat = new AMap.LngLat(+lastGps.longtitude, +lastGps.latitude)
  diffDate.value = getDateDiff(firstGps.recordTime, lastGps.recordTime)
  try {
    const address = await getAddress([start.LngLat, end.LngLat])
    start.address = address[0].formattedAddress
    end.address = address[1].formattedAddress
  } catch (error) {
    console.error(error)
  }
}
const polyLinePath = ref<AMap.LngLat[]>([])
/** 转换数据用于初始化运营区域 */
const handleCoordinates = (data: coordinatesType[]) => {
  return data.map(
    (location: coordinatesType) => new AMap.LngLat(location.longtitude, location.latitude)
  )
}
/** 转换数据用于初始化海量点 */
const handleReturnLocation = (data: returnLocationType[]) => {
  return data.map((location: returnLocationType) => {
    return {
      lnglat: [location.longtitude, location.latitude] as [number, number],
      ...location
    }
  })
}
const handleOriginData = () => {
  const bikeGpsList = originData.value?.bikeGpsList
  polyLinePath.value = bikeGpsList!.map((item) => new AMap.LngLat(+item.longtitude, +item.latitude))
}
/**
 * @method handleCoverInit 处理数据生成地图覆盖物
 * @constant marker 骑行车辆
 * @constant polyLines - 每个开关锁数据的轨迹线段数组
 * @constant passedPolyline - 车辆轨迹播放时经过的线段
 * @constant startMarker 开锁点
 * @constant endMarker 关锁点
 * @constant stepMarkers stepMarker横跨点数组
 */
const marker = ref<AMap.Marker>()
const polyLine = ref<AMap.Polyline>()
const passedPolyline = ref<AMap.Polyline>()
const startMarker = ref<AMap.LabelMarker>()
const endMarker = ref<AMap.LabelMarker>()
const stLabelLayer = ref<AMap.LabelsLayer>()
const markerDuration = ref<number>(1000)
const coordinates = ref<AMap.LngLat[]>([])
const returnLocation = ref<returnLocationMapType[]>([])
const massmarks = ref<AMap.MassMarks>()
const infoWindow = shallowRef<AMap.InfoWindow>()
const circle = ref<AMap.Circle>()
const distance = ref<number>(0)
const singleInfoWindow = shallowRef<AMap.InfoWindow>()
interface returnLocationMapType extends returnLocationType {
  lnglat: [number, number]
}
const handleCoverInit = () => {
  marker.value = new AMap.Marker({
    map: map.value!,
    position: start.LngLat!,
    icon: MarkerIcon,
    offset: new AMap.Pixel(-29, -53),
    topWhenClick: true
  })
  stLabelLayer.value = new AMap.LabelsLayer({
    collision: false,
    allowCollision: true
  })
  startMarker.value = getStartMarkerCover()
  endMarker.value = getEndMarkerCover()
  stLabelLayer.value.add([startMarker.value, endMarker.value])
  map.value?.add(stLabelLayer.value)
  renderPolyline()
  renderReturnLocation()
  handleContinueMarker()
  renderPoint()
  renderScopeOperate()
  map.value?.setFitView([startMarker.value, endMarker.value])
}
const handleSingleCoverInit = async () => {
  const data = originData.value?.bikeGpsList
  const lastGps = data![data!.length - 1]
  end.lockTime = lastGps.recordTime
  end.LngLat = new AMap.LngLat(+lastGps.longtitude, +lastGps.latitude)
  try {
    const address = await getAddress([end.LngLat])
    end.address = address[0].formattedAddress
    singleInfoWindow.value = new AMap.InfoWindow({
      autoMove: true,
      offset: new AMap.Pixel(0, -50),
      isCustom: true,
      content: `<div class="single-infowindow">${end.lockTime}</div>`
    })
    singleInfoWindow.value.open(map.value!, end.LngLat)
  } catch (error) {
    console.error(error)
  }
  stLabelLayer.value = new AMap.LabelsLayer({
    collision: false,
    allowCollision: true
  })
  endMarker.value = getEndMarkerCover()
  stLabelLayer.value.add([endMarker.value])
  map.value?.add(stLabelLayer.value)
  renderReturnLocation()
  renderScopeOperate()
  map.value?.setFitView([endMarker.value])
}
const renderPolyline = () => {
  polyLine.value = new AMap.Polyline({
    map: map.value!,
    path: polyLinePath.value,
    strokeColor: '#999999',
    strokeOpacity: 1,
    strokeWeight: 6,
    strokeStyle: 'solid',
    showDir: true,
    lineJoin: 'round'
  })
  //经过线段
  passedPolyline.value = new AMap.Polyline({
    map: map.value!,
    strokeColor: '#3677EC',
    strokeOpacity: 1,
    strokeWeight: 6,
    strokeStyle: 'solid',
    showDir: true,
    lineJoin: 'round'
  })
  distance.value = AMap.GeometryUtil.distanceOfLine(polyLinePath.value)
}
const renderReturnLocation = () => {
  massmarks.value = new AMap.MassMarks(returnLocation.value, {
    style: getStyle(),
    zIndex: 110
  })
  infoWindow.value = new AMap.InfoWindow({
    autoMove: true,
    offset: new AMap.Pixel(15, 0),
    isCustom: true
  })
  massmarks.value.setMap(map.value)
  massmarks.value.on('click', handleMassMarksClick)
  //定义车辆回放轨迹事件 在执行moveTo，moveAlong动画时触发事件
  marker.value?.on('moving', handleBikeMoving)
}
const renderPoint = () => {
  circle.value = new AMap.Circle({
    fillColor: '#F3860A',
    fillOpacity: 0.1,
    strokeOpacity: 0
  })
  map.value?.add(circle.value)
  initPoint()
}
const renderScopeOperate = () => {
  if (coordinates.value.length > 0) {
    const polygon = new AMap.Polygon({
      path: coordinates.value,
      strokeColor: '#418DFF',
      strokeOpacity: 1,
      strokeWeight: 3,
      fillColor: '#418DFF',
      fillOpacity: 0.1,
      strokeStyle: 'dashed',
      bubble: true
    })
    map.value?.add(polygon)
  }
}
/** 轨迹点初始化*/
const LocusPointRef = ref<InstanceType<typeof LocusPoint> | null>(null)
const labelsLayer = shallowRef<AMap.LabelsLayer>() // 创建一个标注层实例
const textMarker = shallowRef<AMap.Text>()
const distanceText = shallowRef<AMap.Text>()
const Icon = reactive([
  {
    type: 'image',
    // 图片 url
    image: CircleImg,
    // 图片尺寸
    size: [20, 20] as [number, number],
    anchor: 'center',
    clipOrigin: [0, 0] as [number, number],
    clipSize: [20, 20] as [number, number]
  },
  {
    type: 'image',
    // 图片 url
    image: ActiveCircleImg,
    // 图片尺寸
    size: [20, 20] as [number, number],
    anchor: 'center',
    clipOrigin: [0, 0] as [number, number],
    clipSize: [20, 20] as [number, number]
  },
  {
    type: 'image',
    // 图片 url
    image: CircleImg,
    // 图片尺寸
    size: [25, 25] as [number, number],
    anchor: 'center',
    clipOrigin: [0, 0] as [number, number],
    clipSize: [20, 20] as [number, number]
  },
  {
    type: 'image',
    // 图片 url
    image: ActiveCircleImg,
    // 图片尺寸
    size: [25, 25] as [number, number],
    anchor: 'center',
    clipOrigin: [0, 0] as [number, number],
    clipSize: [20, 20] as [number, number]
  }
])
const initPoint = () => {
  // 创建一个标注层实例
  labelsLayer.value = new AMap.LabelsLayer({
    collision: false,
    allowCollision: true,
    zIndex: 200
  })
  textMarker.value = new AMap.Text({
    map: map.value!,
    anchor: 'top-center',
    topWhenClick: true,
    style: {
      padding: '5px 10px',
      marginTop: '1rem',
      borderRadius: '.25rem',
      backgroundColor: 'white',
      borderWidth: '0',
      boxShadow: '0 2px 6px 0 #606266',
      textAlign: 'center',
      fontSize: '12px',
      color: '#606266'
    },
    offset: new AMap.Pixel(0, 20)
  })
  distanceText.value = new AMap.Text({
    map: map.value!,
    anchor: 'top-center',
    topWhenClick: true,
    style: {
      padding: '5px 10px',
      marginTop: '1rem',
      borderRadius: '.25rem',
      backgroundColor: 'white',
      borderWidth: '0',
      boxShadow: '0 2px 6px 0 #606266',
      textAlign: 'center',
      fontSize: '12px',
      color: '#606266'
    }
  })
  textMarker.value.hide()
  distanceText.value.hide()
  const data = originData.value?.bikeGpsList
  polyLinePath.value.forEach((item, index) => {
    const labelMarker = new AMap.LabelMarker({
      position: item,
      extData: data?.[index],
      text: {
        content: (index + 1).toString(),
        direction: 'center',
        offset: index + 1 >= 100 ? [0, -3] : [0, -3],
        style: {
          fontSize: index + 1 >= 100 ? 10 : 12,
          fillColor: '#606266',
          padding: [0, 0, 0, 0]
        }
      },
      icon: index + 1 >= 100 ? Icon[2] : Icon[0]
    })
    labelMarker.on('mouseover', handleLabelMarkerMouseOver)
    labelMarker.on('mouseout', handleLabelMarkerMouseOut)
    labelsLayer.value?.add(labelMarker)
  })
  map.value?.add(labelsLayer.value)
}
const handleLabelMarkerMouseOver = (e: AMap.MapsEvent) => {
  textMarker.value?.setText(e.target.getExtData().recordTime)
  textMarker.value?.setPosition(e.target.getPosition())
  setLabelMarkerStyle('active', e.target)
  textMarker.value?.show()
}
const handleLabelMarkerMouseOut = (e: AMap.MapsEvent) => {
  setLabelMarkerStyle('default', e.target)
  textMarker.value?.hide()
}
const setLabelMarkerStyle = (type: string, marker: AMap.LabelMarker) => {
  const text = marker.getText()!
  const activeColor = '#FFF'
  const color = '#606266'
  const content = +text.content!
  if (type === 'active') {
    text.style!.fillColor = activeColor
    marker.setIcon(content >= 100 ? Icon[3] : Icon[1])
  } else {
    text.style!.fillColor = color
    marker.setIcon(content >= 100 ? Icon[2] : Icon[0])
  }
  marker.setText(text)
}
/** 海量点图层样式 */
const getStyle = () => {
  return [
    {
      anchor: new AMap.Pixel(0, 0),
      url: returnPointImg,
      size: new AMap.Size(30, 31)
    },
    {
      anchor: new AMap.Pixel(0, 0),
      url: activeReturnPointImg,
      size: new AMap.Size(30, 31)
    }
  ]
}
/** 点击海量点的事件 */
const handleMassMarksClick = (e: any) => {
  const index = returnLocation.value.findIndex(
    (item) => item.lnglat[1] === e.data.latitude && item.lnglat[0] === e.data.longtitude
  )
  circle.value?.setCenter(e.data.lnglat)
  circle.value?.setRadius(e.data.radius)
  if (infoWindow.value?.getIsOpen()) {
    infoWindow.value.close()
    returnLocation.value = returnLocation.value.map((item) => {
      return {
        ...item,
        style: 0
      }
    })
    massmarks.value?.setData(returnLocation.value)
    circle.value?.hide()
  } else {
    returnLocation.value = returnLocation.value.map((item, i) => {
      if (index == i) {
        return {
          ...item,
          style: 1
        }
      } else {
        return {
          ...item,
          style: 0
        }
      }
    })
    massmarks.value?.setData(returnLocation.value)
    geocoder.value.getAddress(e.data.lnglat, (status: any, result: any) => {
      if (result.info == 'OK') {
        const name = result.regeocode.aois
          ? result.regeocode.aois[0].name
          : result.regeocode.formattedAddress
        infoWindow.value?.setContent(
          createReturnLocationContent(e.data.address, e.data.returnLocationsId, name)
        )
      } else {
        // 处理获取地址失败的情况
        ElMessage.error('地址解析失败')
        infoWindow.value?.setContent(
          createReturnLocationContent(e.data.address, e.data.returnLocationsId, '')
        )
      }
      infoWindow.value?.open(map.value!, e.data.lnglat)
      circle.value?.show()
      map.value?.setCenter(e.data.lnglat)
    })
  }
  map.value?.setFitView([circle.value!!])
}
/** 海量点信息窗体内容 */
const createReturnLocationContent = (address: string, returnLocationsId: number, title: string) => {
  return `<div class="return-point-infowindow">
                  <div class="return-point-infowindow__title">
                    <span class="return-point-infowindow__name">${title}</span>
                    <div class="return-point-infowindow__id-content">
                        <span>编号:${returnLocationsId}</span>
                    </div>
                  </div>
                  <div class="return-point-infowindow__address">
                    <span>${address}</span>
                  </div>
              </div>`
}
/**
 * @description 轨迹回放事件回调函数
 * @param e 事件参数 包含 {index:number,process:number,type:string,passedPath:Proxy(t)[],passedPos:Proxy(t),pos:t}
 * @param process - 动画进程 当为1时代表 点到点的动画结束
 * @param index - 在轨迹数据数组中的index索引
 */
const handleBikeMoving = (e: any) => {
  if (e.progress === 1) {
    marker.value?.setLabel({
      content: `${originData.value?.bikeGpsList![e.index].recordTime}`,
      direction: 'top'
    })
  }
  passedPolyline.value?.setPath(e.passedPath)
}
/**
 * 执行movealong动画后事件
 *
 */
/** 速度变化 */
const handleSpeedChange = (speed: number) => {
  const basicSpeed = 1000
  markerDuration.value = basicSpeed / speed
  marker.value?.moveAlong(polyLinePath.value, {
    aniInterval: 0,
    autoRotation: false,
    duration: markerDuration.value
  })
}
/** 暂停 */
const handleStopMarker = () => {
  marker.value?.pauseMove()
}
/** 继续 */
const handleContinueMarker = () => {
  if (
    (marker.value?.getPosition()?.getLat() === start.LngLat?.getLat() &&
      marker.value?.getPosition()?.getLng() === start.LngLat?.getLng()) ||
    (marker.value?.getPosition()?.getLat() === end.LngLat?.getLat() &&
      marker.value?.getPosition()?.getLng() === end.LngLat?.getLng())
  ) {
    marker.value?.moveAlong(polyLinePath.value, {
      aniInterval: 0,
      autoRotation: false,
      duration: markerDuration.value
    })
  } else {
    marker.value?.resumeMove()
  }
}
/** 重新初始化地图 即 清空 */
const reset = () => {
  map.value?.clearMap()
  console.log(marker.value)
}
/** -------------------辅助函数-------------- */

const NoSingleLngLat = computed(() => originData.value?.bikeGpsList?.length! > 1)
/**
 * 生成起点
 */
const getStartMarkerCover = () => {
  return new AMap.LabelMarker({
    position: start.LngLat!,
    icon: {
      image: StartIcon,
      anchor: 'bottom-center',
      clipOrigin: [0, 0],
      clipSize: [44, 44],
      size: [44, 44],
      offset: new AMap.Pixel(0, 0)
    },
    text: {
      content: '起点:' + start.unlockTime,
      direction: 'top',
      style: {
        fontSize: 12,
        fillColor: '#606266',
        backgroundColor: '#FFF',
        padding: [0, 0, 0, 0]
      }
    }
  })
}
/**
 * 生成终点
 */
const getEndMarkerCover = () => {
  return new AMap.LabelMarker({
    position: end.LngLat!,
    icon: {
      image: EndIcon,
      anchor: 'bottom-center',
      clipOrigin: [0, 0],
      clipSize: [44, 44],
      size: [44, 44],
      offset: new AMap.Pixel(0, 0)
    },
    text: {
      content: '终点:' + end.lockTime,
      direction: 'top',
      style: {
        fontSize: 12,
        fillColor: '#606266',
        backgroundColor: '#FFF',
        padding: [0, 0, 0, 0]
      }
    }
  })
}
/** 计算骑行时间差 */
const getDateDiff = (startDateString: string, endDateString: string) => {
  // 创建起始日期和结束日期对象
  const startDate = dayjs(startDateString, 'YYYY-MM-DD HH:mm:ss')
  const endDate = dayjs(endDateString, 'YYYY-MM-DD HH:mm:ss')

  // 计算日期差异
  const diff = endDate.diff(startDate)
  // 提取差异的时间单位
  const duration = dayjs.duration(diff)
  const years = duration.years()
  const months = duration.months()
  const days = duration.days()
  const hours = duration.hours()
  const minutes = duration.minutes()
  const seconds = duration.seconds()
  let formattedDiff = ''
  if (years > 0) formattedDiff = formattedDiff.concat(years + '年')
  if (months > 0) formattedDiff = formattedDiff.concat(months + '月')
  if (days > 0) formattedDiff = formattedDiff.concat(days + '天')
  if (hours > 0) formattedDiff = formattedDiff.concat(hours + '时')
  if (minutes > 0) formattedDiff = formattedDiff.concat(minutes + '分')
  if (seconds > 0) formattedDiff = formattedDiff = formattedDiff.concat(seconds + '秒')
  return formattedDiff
}
/** 获取地址 */
const getAddress = (data: AMap.LngLat[] | AMap.LngLat): any => {
  return new Promise((resolve, reject) => {
    geocoder.value.getAddress(data, (status: string, result: any) => {
      if (status === 'complete') {
        if (Array.isArray(data)) {
          resolve(result.regeocodes)
        } else {
          resolve(result.regeocode)
        }
      } else {
        reject(new Error(`获取地址失败`))
      }
    })
  })
}
/** 实际距离测量 */
const selectedPoints = ref<AMap.LabelMarker[]>([])
const actualDistance = ref('0米')
const isActual = ref(false)
// 用于存储上次点击的两个点
const activeMarkers = ref<AMap.LabelMarker[]>([])
const handleLabelMarkerClick = (e: AMap.MapsEvent) => {
  const clickedPoint = e.target

  // 如果点击的是相同点
  if (
    selectedPoints.value.length === 1 &&
    isSameLngLat(selectedPoints.value[0].getPosition(), clickedPoint.getPosition())
  ) {
    ElMessage.warning('点击了相同的点，请选择不同的点')
    setLabelMarkerStyle('default', clickedPoint)
    return
  }
  // **恢复上次点击的点样式**
  if (selectedPoints.value.length === 0) {
    actualDistance.value = '0米'
    activeMarkers.value.forEach((marker) => setLabelMarkerStyle('default', marker))
    activeMarkers.value = []
  }
  // 记录点击点
  selectedPoints.value.push(clickedPoint)
  // **设置当前点为 active 样式**
  setLabelMarkerStyle('active', clickedPoint)
  distanceText.value?.hide()
  if (selectedPoints.value.length === 2) {
    const [startPoint, endPoint] = selectedPoints.value

    // 找出路径中包含 startPoint 和 endPoint 的子路径
    const startIndex = polyLinePath.value.findIndex((point) =>
      isSameLngLat(point, startPoint.getPosition())
    )
    const endIndex = polyLinePath.value.findIndex((point) =>
      isSameLngLat(point, endPoint.getPosition())
    )
    if (startIndex === -1 || endIndex === -1) {
      ElMessage.error('选定点不在轨迹路径中')
      selectedPoints.value = []
      return
    }

    // 获取子路径
    const subPath =
      startIndex < endIndex
        ? polyLinePath.value.slice(startIndex, endIndex + 1)
        : polyLinePath.value.slice(endIndex, startIndex + 1)

    // 获取标注图层中所有标注对象
    const allMarkers = labelsLayer.value?.getAllOverlays() as AMap.LabelMarker[]
    // **设置子路径点的样式为 active**
    subPath.forEach((pathPoint) => {
      const marker = allMarkers.find((m) => isSameLngLat(m.getPosition(), pathPoint)) as
        | AMap.LabelMarker
        | undefined

      if (marker) {
        setLabelMarkerStyle('active', marker)
        activeMarkers.value.push(marker)
      }
    })
    // 使用 GeometryUtil.distanceOfLine 计算路径距离
    actualDistance.value = AMap.GeometryUtil.distanceOfLine(subPath).toFixed(2)
    distanceText.value?.setText(
      '实际距离' +
        `<span style="color:var(--xy-primary-color)">${actualDistance.value}</span>` +
        '米'
    )
    distanceText.value?.setPosition(selectedPoints.value[1].getPosition())
    distanceText.value?.show()
    // 清空记录以便下一次测量
    selectedPoints.value = []
  }
}
const handleActual = () => {
  isActual.value = true
  LocusPointRef.value?.setStatus(true)
  labelsLayer.value?.getAllOverlays()?.forEach((item) => {
    item.off('mouseover', handleLabelMarkerMouseOver)
    item.off('mouseout', handleLabelMarkerMouseOut)
    item.on('click', handleLabelMarkerClick, item, true)
  })
}
const isSameLngLat = (start: AMap.LngLat, end: AMap.LngLat) => {
  if (start.getLat() === end.getLat() && start.getLng() === end.getLng()) {
    return true
  } else {
    return false
  }
}
/** 卸载实际距离测量 */
const handleUnactual = () => {
  isActual.value = false
  actualDistance.value = '0米'
  LocusPointRef.value?.setStatus(false)
  activeMarkers.value.forEach((marker) => setLabelMarkerStyle('default', marker))
  activeMarkers.value = []
  distanceText.value?.hide()
  labelsLayer.value?.getAllOverlays()?.forEach((item) => {
    item.on('mouseover', handleLabelMarkerMouseOver)
    item.on('mouseout', handleLabelMarkerMouseOut)
    item.off('click', handleLabelMarkerClick)
  })
}
/** 打开轨迹时间 */
const openPoint = () => {
  labelsLayer.value?.show()
}
/** 关闭轨迹时间 */
const closePoint = () => {
  labelsLayer.value?.hide()
}
onMounted(() => {
  init()
})
/** 处理是否缓存 */
onActivated(() => {
  LocusPointRef.value?.setStatus(false)
  watchParams.bikeId = route.query.bikeId as string
  watchParams.orderId = route.query.orderId as string
})
useActivated(
  watchParams,
  { watchParams },
  [
    { key: 'bikeId', path: 'watchParams.bikeId' },
    { key: 'orderId', path: 'watchParams.orderId' }
  ],
  getData,
  []
)
</script>

<template>
  <div class="xy-map-container">
    <div ref="mapContainer" id="map-container" v-loading="loading">
      <search-place :auto="auto" :map="map!" :place-search="placeSearch" />
      <locus-control-group
        v-if="NoSingleLngLat"
        @stop="handleStopMarker"
        @continue="handleContinueMarker"
        @speed-change="handleSpeedChange"
      />
      <div class="tools-container">
        <locus-point ref="LocusPointRef" @open="openPoint" @close="closePoint" />
        <el-divider direction="vertical" />
        <measure-tools
          :ruler="ruler"
          :actual="NoSingleLngLat"
          @actual="handleActual"
          @unactual="handleUnactual"
        />
      </div>
      <div class="location-info" v-if="NoSingleLngLat">
        <div class="location-info__item">
          <img :src="StartIcon" alt="" w-30 h-30 mr-5 />
          <div border border-solid class="border-[#e4e7ed]" p-5 max-w-220 text-10>
            <span leading-snug>{{ start.address }}</span>
            <div leading-snug>{{ start.unlockTime }}</div>
          </div>
        </div>
        <div class="location-info__item">
          <img :src="EndIcon" alt="" w-30 h-30 mr-5 />
          <div border border-solid class="border-[#e4e7ed]" p-5 max-w-220 text-10>
            <span leading-snug>{{ end.address }}</span>
            <div leading-snug>{{ end.lockTime }}</div>
          </div>
        </div>
        <div class="location-info__footer" text-10>
          <span mr-30>本次骑行用时:{{ diffDate }}</span>
          <span>本次骑行距离:{{ distance.toFixed(2) }}米</span>
        </div>
      </div>
    </div>
  </div>
</template>

<style scoped lang="scss">
:deep(.address) {
  font-size: 14px;
  font-family: PingFang SC;
  line-height: 20px;
  color: var(--xy-medium-text-color);
}
:deep(.time) {
  font-size: 12px;
  font-family: PingFang SC;
  line-height: 17px;
  color: var(--xy-grey-text-color);
}
:deep(.amap-marker-label) {
  background-color: #fff;
  white-space: nowrap;
  cursor: default;
  padding: 3px;
  font-size: 12px;
  line-height: 14px;
  color: #333333;
  box-shadow: 0px 2px 8px 0px rgba(0, 0, 0, 0.25);
  border-radius: 4px 4px 4px 4px;
  border: none;
}
:deep(.return-point-infowindow) {
  z-index: 999;
  position: relative;
  display: flex;
  flex-direction: column;
  background: #ffffff;
  box-shadow: 0px 3px 6px 1px rgba(0, 0, 0, 0.16);
  border-radius: 5px 5px 5px 5px;
  padding: 10px;
  .return-point-infowindow__title {
    display: flex;
    align-items: center;
    white-space: nowrap;
    .return-point-infowindow__name {
      font-weight: 500;
      font-size: 16px;
      color: rgba(51, 51, 51, 0.99);
      line-height: 22px;
    }
    .return-point-infowindow__id-content {
      line-height: 19px;
      background: rgba(243, 134, 10, 0.1);
      border-radius: 2px 2px 2px 2px;
      padding: 1px 4px;
      display: inline-block;
      text-align: center;
      font-size: 12px;
      color: #f3860a;
      margin-left: 10px;
    }
  }
  .return-point-infowindow__address {
    font-size: 14px;
    color: rgba(102, 102, 102, 0.99);
    line-height: 19px;
    white-space: normal;
  }
}
.location-info {
  position: absolute;
  z-index: 999;
  top: 80px;
  left: 20px;
  padding: 10px;
  border-radius: 4px 4px 4px 4px;
  background: #ffffff;
  display: flex;
  flex-direction: column;
  transition: height 1s;
  &__item {
    display: flex;
    align-items: center;
    margin-bottom: 15px;
  }
  &__footer {
    display: flex;
    align-items: center;
    justify-content: space-around;
  }
}
:deep(.single-infowindow) {
  background-color: #fff;
  padding: 10px;
  border-radius: 10px;
}
:deep(.tools-container) {
  display: flex;
  align-items: center;
  position: absolute;
  top: 20px;
  right: 70px;
  z-index: 200;
  background-color: #fff;
  padding: 10px 10px;
  box-shadow: 0px 0px 10px 1px rgba(0, 0, 0, 0.1);
  border-radius: 5px 5px 5px 5px;
}
</style>
